/* Copyright (c) 2001 IBK-Landquart-Switzerland. All rights reserved.
 *
 * Module      :  ZBlock.cpp
 * Application :  CSL kernel
 * Purpose     :  Block
 *
 * Date        Description                                 Who
 * --------------------------------------------------------------------------
 * 2001.05.21  First implementation                        P.Koch, IBK
 * 2001.07.07  Renaming from css to csl                    P.Koch, IBK
 * 2001.07.28  Enhanced trace facilities                   P.Koch, IBK
 *
 * OPEN SOURCE LICENSE
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to IBK at info@ibk-software.ch.
 */

#define ZC_BUILDING_ZCSL

#include <ZCsl.hpp>
#include "Internal.h"

ZCsl::Block::Block(ZCsl* aParent, Block* aPrev, const ZString& aName) :
   iVars(0),
   iFuncs(0),
   iPrev(aPrev),
   iParent(aParent),
   iCatch(-1),
   iName(aName)
{
   ZFUNCTRACE_DEVELOP("ZCsl::Block::Block(ZCsl* aParent, Block* aPrev)");
} // Block

ZCsl::Block::~Block()
{
   ZFUNCTRACE_DEVELOP("ZCsl::Block::~Block()");
   if (iVars) delete iVars;
   if (iFuncs) delete iFuncs;
   if (iPrev) delete iPrev;
} // ~Block

ZCsl::Variable* ZCsl::Block::findVar(const ZString& aVarName, ZBoolean aFail)
{
   ZFUNCTRACE_DEVELOP("ZCsl::Block::findVar(const ZString& aVarName, ZBoolean aFail)");
   Variable* v = iVars;
   while (v) {
      if (v->match(aVarName)) return v;
      v = v->iPrev;
   } // while
   if (aFail) iParent->throwExcept(msgVarNotFound, aVarName);
   return v;
} // findVar

ZCsl::Variable* ZCsl::Block::addVar(
   const ZString& aVarName,
   const ZString& aInitValue,
   ZBoolean aIsConst,
   ZBoolean aIsRef,
   ZBoolean aIsKnown,
   ZBoolean aIsExtern)
{
   ZFUNCTRACE_DEVELOP("ZCsl::Block::addVar(...)");
   Variable* v = findVar(aVarName, zFalse);
   if (v) {
      if (!v->iIsExtern)
         iParent->throwExcept(msgVarAlrdyDef, aVarName);
      if (v->iIsConst != aIsConst ||
          (v->iRef && !aIsRef)    ||
          (!v->iRef && aIsRef)    ||
          aVarName.occurrencesOf('[') != v->dims() )
         iParent->throwExcept(msgVarDiffers, aVarName);
      Variable var(iParent, aVarName, aInitValue,
                   aIsConst, aIsRef, aIsKnown, aIsExtern, 0);
      if (v->iVals) delete [] v->iVals;
      v->iVals = var.iVals;
      var.iVals = 0;
      v->iIsKnown = var.iIsKnown;
      v->iIsExtern = var.iIsExtern;
      for (int i = 0; i < MAXDIMS; i++)
         v->iDims[i] = var.iDims[i];
      return v;
   } // if
   iVars = new Variable(iParent, aVarName, aInitValue,
                        aIsConst, aIsRef, aIsKnown, aIsExtern, iVars);
   return iVars;
} // addVar
